package com.cskaoyan.shopping.service.impl;

import com.cskaoyan.mall.commons.exception.BizException;
import com.cskaoyan.shopping.constants.ShoppingRetCode;
import com.cskaoyan.shopping.converter.CartItemConverter;
import com.cskaoyan.shopping.dal.entitys.Item;
import com.cskaoyan.shopping.dal.entitys.ItemStock;
import com.cskaoyan.shopping.dal.persistence.ItemMapper;
import com.cskaoyan.shopping.dal.persistence.ItemStockMapper;
import com.cskaoyan.shopping.dto.CartProductDto;
import com.cskaoyan.shopping.form.CartRequest;
import com.cskaoyan.shopping.form.CheckAllItemRequest;
import com.cskaoyan.shopping.service.ICartService;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.validation.constraints.NotNull;
import java.util.*;

/**
 * @author doublec
 * @since 2022/10/25 16:24
 */

@Service
public class ICartServiceImpl implements ICartService {
    @Autowired
    RedissonClient redissonClient;

    @Autowired
    ItemMapper itemMapper;

    @Autowired
    CartItemConverter cartItemConverter;

    @Autowired
    ItemStockMapper itemStockMapper;

    /**
     * 根据用户Id获取到Redis数据库中购车的所有信息
     * @param userId
     * @return
     */
    @Override
    public List<CartProductDto> getCartListById(Long userId) {
        List<CartProductDto> list = new LinkedList<>();
        //获取到名为userId的hash数据结构的值
        Map<Long, CartProductDto> map = redissonClient.getMap(userId.toString());
        //从该hash数据结构获取到所有的filed的集合视图
        Set<Long> productIds = map.keySet();
        //遍历所有的filed，根据filed获取到对应的value，也就是对应的商品对象
        Iterator<Long> iterator = productIds.iterator();
        while(iterator.hasNext()){
            Long productId = iterator.next();
            //将获取到的商品对象放入返回的list当中
            CartProductDto cartProductDto = map.get(productId);
            list.add(cartProductDto);
        }
        //返回redis数据库中的所有购物车商品信息
        return list;
    }

    /**
     * 添加商品到购物车
     * @param request
     * @return
     */
    @Override
    public Integer addToCart(CartRequest request) {
        //获取userId，作为Redis数据库中的key值
        @NotNull Long userId = request.getUserId();
        //获取到key为userId的数据结构的值
        RMap<Long, CartProductDto> map = redissonClient.getMap(userId.toString());
        @NotNull Long productId = request.getProductId();
        //根据productId在tb_stock表中查询商品的数量，看是否有库存，以及是否满足限购数量
        ItemStock itemStock = itemStockMapper.selectByPrimaryKey(productId);
        Long stockCount = itemStock.getStockCount();
        Integer restrictCount = itemStock.getRestrictCount();
        Integer productNum = request.getProductNum();
//        if (stockCount.intValue()==0 || stockCount.intValue()<productNum){
//            return 0;
//        }
        if (productNum>restrictCount){
            return 1;
        }
        //现在redis数据库中找到是否有该商品的信息，如果有的话，直接增加相应的数量
        CartProductDto cartProductDto1 = map.get(productId);
        long value = productNum.longValue();
        if (cartProductDto1 != null){
            Long productNum1 = cartProductDto1.getProductNum();
            Long newValue = value + productNum1;
            cartProductDto1.setProductNum(newValue);
            map.put(productId,cartProductDto1);
            return 2;
        }
        //根据productId在mysql数据库中寻找相应的商品信息，封装到CartProductDto中
        Item item = itemMapper.selectByPrimaryKey(productId);
        CartProductDto cartProductDto = cartItemConverter.item2Dto(item);
        //获取加入到购物车的数量
        cartProductDto.setProductNum(value);
        cartProductDto.setChecked("true");
        //将这个cartProductDto对象放入到redis当中
        map.put(productId,cartProductDto);
        return 2;
    }

    /**
     * 更新购物车中的商品
     * @param request
     * @return
     */
    @Override
    public Integer updateCartNum(CartRequest request) {
        //获取到userId
        @NotNull Long userId = request.getUserId();
        //根据userId获取到对应数据结构的值
        RMap<Long, CartProductDto> map = redissonClient.getMap(userId.toString());
        //获取到productId作为Filed
        @NotNull Long productId = request.getProductId();
        ItemStock itemStock = itemStockMapper.selectByPrimaryKey(productId);
        Long stockCount = itemStock.getStockCount();
        Integer restrictCount = itemStock.getRestrictCount();
        Integer productNum = request.getProductNum();
//        if (stockCount.intValue()==0 || stockCount.intValue()<productNum){
//            return 0;
//        }
        if (productNum>restrictCount){
            return 1;
        }
        //根据filed获取到相应的value
        CartProductDto cartProductDto = map.get(productId);
        //修改cartProductDto的num值
        cartProductDto.setProductNum(productNum.longValue());
        //修改cartProductDto的checked值
        String checked = request.getChecked();
        cartProductDto.setChecked(checked);
        //将修改了productNum之后的cartProductDto重新放入到Redis当中
        map.put(productId,cartProductDto);
        return 2;
    }


    /**
     * 全选购物车的商品
     * @param request
     */
    @Override
    public void checkAllCartItem(CheckAllItemRequest request) {
        //根据userId获取到对用的数据结构的值
        @NotNull Long userId = request.getUserId();
        RMap<Long, CartProductDto> map = redissonClient.getMap(userId.toString());
        //获取到checked状态
        @NotNull String checked = request.getChecked();
        //获取所有的filed
        Set<Long> productIds = map.keySet();
        Iterator<Long> iterator = productIds.iterator();
        while(iterator.hasNext()){
            Long productId = iterator.next();
            //遍历所有的filed，将对应的value的checked属性修改为传过来的参数状态
            CartProductDto cartProductDto = map.get(productId);
            cartProductDto.setChecked(checked);
            //将修改了状态后的cartProductDto重新放入redis中
            map.put(productId,cartProductDto);
        }
    }


    /**
     * 删除购物车中的商品
     * @param uid
     * @param itemId
     */
    @Override
    public void deleteCartItem(Long uid, Long itemId) {
        //根据uid找到redis中的数据结构的值
        RMap<Long, CartProductDto> map = redissonClient.getMap(uid.toString());
        //根据productId找到删除对应的数据
        CartProductDto remove = map.remove(itemId);
    }


    /**
     * 删除购物车中选中的商品
     * @param userId
     */
    @Override
    public void deleteCheckedItem(Long userId) {
        //根据userId获取到Redis相应的数据结构的值
        RMap<Long, CartProductDto> map = redissonClient.getMap(userId.toString());
        //获取到所有的filed
        Set<Long> productIds = map.keySet();
        Iterator<Long> iterator = productIds.iterator();
        while(iterator.hasNext()){
            Long productId = iterator.next();
            //根据productId获取对应的购物车信息
            CartProductDto cartProductDto = map.get(productId);
            if (cartProductDto.getChecked().equals("true")){
                //如果当前购物车对象信息的checked状态为true，就从redis中删除
                map.remove(productId);
            }
        }
    }
}
